home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Utilities
/
BackSpace
/
Source
/
ThinkMore.m
< prev
next >
Wrap
Text File
|
1993-07-14
|
10KB
|
435 lines
// ThinkMore.m
//
// Contains additional methods used in the Thinker class.
//
// You may freely copy, distribute, and reuse the code in this example.
// NeXT disclaims any warranty of any kind, expressed or implied, as to its
// fitness for any particular use.
#import "Thinker.h"
#import "SpaceView.h"
#import "BackView.h"
#import "SleepView.h"
#import "BlackView.h"
#import "Password.h"
#import "psfuncts.h"
#import <appkit/appkit.h>
#import <objc/NXBundle.h>
#define VIEWDIRECTORY "/LocalLibrary/BackSpaceViews"
static char *compiledViewNames[] = {
"Space",
"Boink",
"Black",
};
#define COMVIEWCOUNT (sizeof(compiledViewNames)/sizeof(*compiledViewNames))
@implementation Thinker(thinkMore)
//must invoke this before creating window or setting up the views
- getViewType
{
int i;
id theMatrix;
char buf[MAXPATHLEN];
ModuleInfo *m;
strcpy( buf, NXHomeDirectory());
strcat( buf, "/Library/BackSpaceViews");
moduleList = [[ModuleList alloc] init];
[self loadViewsFrom:buf];
[self loadViewsFrom: [self appDirectory]];
[self loadViewsFrom: VIEWDIRECTORY];
for (i = 0; i < COMVIEWCOUNT; i++)
{
m = [[ModuleInfo alloc]
initWithView:nil name:compiledViewNames[i] path:NULL];
[moduleList addObject: m];
}
[moduleList sort];
[viewSelectionBrowser loadColumnZero];
theMatrix = [viewSelectionBrowser matrixInColumn:0];
[theMatrix selectCellAt:realViewIndex :0];
[theMatrix scrollCellToVisible:realViewIndex :0];
return self;
}
- selectRealViewIndex:sender
{
//sender is the NXBrowser
int index = [[viewSelectionBrowser matrixInColumn:0] selectedRow];
if (index == realViewIndex) return self;
if (index == -1)
{
id theMatrix = [viewSelectionBrowser matrixInColumn:0];
[theMatrix selectCellAt:realViewIndex :0];
[theMatrix scrollCellToVisible:realViewIndex :0];
return self;
}
realViewIndex = index;
[self setVirtualViewIndexAndIncrement:NO];
return self;
}
// this method is the actual view setting mechanism,
// guaranteed to get called to set the view
- setVirtualViewIndexAndIncrement:(BOOL)flag
{
id myView;
id newInspector;
if (realViewIndex)
{
virtualViewIndex = realViewIndex-1;
[self selectScreenSaverViews];
}
else
{
if (flag)
{
virtualViewIndex = random() % [moduleList count];
[self selectScreenSaverViews];
myView = [self backView];
while ([myView respondsTo:@selector(isBoringScreenSaver)]
&& [myView isBoringScreenSaver])
{
if (++virtualViewIndex >= [moduleList count])
virtualViewIndex = 0;
[self selectScreenSaverViews];
myView = [self backView];
}
}
else [self selectScreenSaverViews];
}
//---------------------------------------------
// now plug in the inspector
//---------------------------------------------
myView = [self backView];
if ([myView respondsTo:@selector(inspector:)])
{
newInspector = [myView inspector:self];
if (!newInspector) newInspector = [self nullInspector];
}
else newInspector = [self nullInspector];
if (newInspector != currentInspector)
{
if ([oldInspectorOwner respondsTo:@selector(inspectorWillBeRemoved)])
[oldInspectorOwner inspectorWillBeRemoved];
// either myView will be the inspector owner, or it won't care
oldInspectorOwner = myView;
// don't want it to resize the box. Suboptimal technique...
[newInspector setFrame:&inspectorFrame];
[invisibleInspectorBox setContentView: newInspector];
currentInspector = newInspector;
if ([myView respondsTo:@selector(inspectorInstalled)])
[myView inspectorInstalled];
[invisibleInspectorBox display];
}
return self;
}
- selectScreenSaverViews
{
id theView, bigWindow;
int myBacking;
//need to order out big window if that's the type and buffering changed
theView = [self backView];
myBacking = [self backingTypeForView:theView];
[self createBigWindowIfNecessaryForView:theView];
if (myBacking == NX_BUFFERED) bigWindow = bigBufferedWindow;
else bigWindow = bigUnbufferedWindow;
if (windowType == BACKWINDOW)
{
if (spaceWindow != bigWindow)
{
[spaceWindow orderOut:self];
[self useBackWindow:globalTier];
}
}
spaceView = theView;
[self installSpaceViewIntoWindow:spaceWindow];
if ([spaceView respondsTo:@selector(setImage:)])
[spaceView setImage: image];
if ([spaceView respondsTo:@selector(newWindow)]) [spaceView newWindow];
[self setWindowTitle];
NXWriteDefault([NXApp appName], "viewType", (realViewIndex ?
([moduleList nameAt: realViewIndex-1]) : "All"));
if (windowType)
{
// the unbuffered window looks better if you just display
// its contents, but for a buffered oneshot window, you must
// display the window to make sure the window server window exists.
if (myBacking == NX_BUFFERED)
[spaceWindow display];
else
{
[spaceView fillBoundsWithBlack];
[spaceView display];
}
}
if (normalWindow && (windowType == NORMALWINDOW))
{
if (myBacking == NX_BUFFERED)
[normalWindow setBackingType:NX_BUFFERED];
else[normalWindow setBackingType:NX_RETAINED];
}
return self;
}
- setWindowTitle
{
if ([spaceView respondsTo:@selector(windowTitle)])
{
[normalWindow setTitle: NXLocalString([spaceView windowTitle],0,0)];
}
else [normalWindow setTitle: NXLocalString("BackSpace",0,0)];
return self;
}
- getScreenLockerSetting
{
const char *ptr;
[screenLocker setState:0];
ptr = NXGetDefaultValue([NXApp appName], "screenLocker");
if (!ptr || !strcmp(ptr,"Off")) [self setScreenLocker:NO andRemember:NO];
else [self setScreenLocker:YES andRemember:NO];
return self;
}
- changeScreenLockerSetting:sender
{
if (![password checkPassword:
NXLocalString("Enter password to change screen lock setting:",0,0)
randomPos:NO checkLock:NO withView:nil])
{
[screenLocker setState:[password isLocked]];
return self;
}
if (![password validPassword] && ![password setPassword:self])
{
[screenLocker setState:[password isLocked]];
return self;
}
[self setScreenLocker:([screenLocker state])andRemember:YES];
return self;
}
- setScreenLocker:(BOOL)val andRemember:(BOOL)rem
{
[screenLocker setState:val];
[password setLock: val];
if (rem)
{
if (val) NXWriteDefault([NXApp appName], "screenLocker", "On");
else NXRemoveDefault([NXApp appName], "screenLocker");
}
return self;
}
//---------------------------------------------------
// View manager routines
//---------------------------------------------------
- backView
{
NXRect aFrame = {{0,0},{200,200}};
id theView;
if (![moduleList viewAt:virtualViewIndex])
{
char path[MAXPATHLEN];
id myClass;
const char *name;
char *filenames[] = {path, NULL};
ModuleInfo *mp;
struct mach_header *header;
mp = [moduleList objectAt: virtualViewIndex];
name = [mp viewName];
// before I loaded all classes at launch time; now classes are
// loaded only as needed. This idea and some of the code here is
// from bill bumgarner, thanx!
if ([mp path]) // we have path but no instance, must load class
{
long ret;
do
{
sprintf(path, "%s/%sView.BackO", [mp path], name);
ret = objc_loadModules(filenames, NULL, NULL, &header, NULL);
// objc_loadModules succeeds with a warning if the architecture of the
// object file is wrong, so we better check if we really got a class
if (!ret) // load succeeded or was wrong architecture
{
sprintf(path,"%sView", name);
myClass = objc_getClass(path);
if (!myClass) ret = -1;
}
} while (ret && [mp useNextPath]);
[mp discardAltPaths];
if (ret)
{
// Ugh, failed. Will instantiate a BlackView instead...
NXRunAlertPanel([NXApp appName], NXLocalString(
"Could not dynamically load class: %sView",0,0),
NULL, NULL, NULL, name);
name = "Black";
}
else
{
[mp setHeader:header];
}
}
//at this point we must have a valid name for a loaded class
sprintf(path,"%sView", name);
myClass = objc_getClass(path);
theView = [[myClass allocFromZone:backZone] initFrame:&aFrame];
[[moduleList objectAt:virtualViewIndex] setView:theView];
}
theView = [moduleList viewAt:virtualViewIndex];
return theView;
}
- showInfoPanel:sender
{
if (!infoPanel)
{
if (![NXApp loadNibSection:"Info.nib" owner:self withNames:NO fromZone:[self zone]])
NXLogError ("Can't find Info.nib!");
}
[infoPanel makeKeyAndOrderFront:sender];
return self;
}
#define SLEEPSIZE (3.0)
- createSleepWindow
{
if (!sleepWindow)
{
NXRect sleep={{0, 0},{SLEEPSIZE, SLEEPSIZE}};
id aView = [[SleepView alloc] initFrame:&sleep];
sleepWindow = [[Window alloc]
initContent:&sleep style:NX_TOKENSTYLE
backing:NX_NONRETAINED buttonMask:0 defer:NO];
[sleepWindow setEventMask:(NX_MOUSEENTEREDMASK | NX_MOUSEEXITEDMASK)];
PSsetwindowlevel(SLEEPTIER, [sleepWindow windowNum]);
PSWmakeWindowGray([sleepWindow windowNum]);
[[sleepWindow setContentView: aView] free];
[sleepWindow setTrackingRect:&sleep inside:YES owner:aView
tag:3 left:NO right:NO];
}
return self;
}
- setSleepCorner:(int)val
{
NXRect screen={{0, 0}};
NXCoord x = 0.0, y = 0.0;
if (val)
{
[NXApp getScreenSize:&(screen.size)];
[self createSleepWindow];
if (val == 2 || val == 3) x = screen.size.width - SLEEPSIZE;
if (val == 3 || val == 4) y = screen.size.height - SLEEPSIZE;
[sleepWindow moveTo:x :y];
[sleepWindow orderFront:self];
}
else [sleepWindow orderOut:self];
return self;
}
- getHotCornerSetting
{
const char *ptr;
int tval, val=0;
ptr = NXGetDefaultValue([NXApp appName], "hotCorner");
if (ptr)
{
sscanf(ptr,"%d",&tval);
if (tval >= 0 && tval <= 4) val = tval;
}
[cornerView setState:val];
[self setSleepCorner:val];
return self;
}
@end